package xmlcurl

import (
	"callsips/internal/model/customer/cgateway"
	"callsips/internal/model/customer/risk"
	"callsips/internal/model/sips/gateway"
	"callsips/internal/model/yunhu/accounttaocan"
	"callsips/internal/utils"
	"encoding/json"
	"encoding/xml"
	"fmt"
)

// 拨号计划测试
func XMLDialplanTextContext(destinationNumber string, destNumber string, contextName string, accountTaocan *accounttaocan.YunhuAccountTaocan) []*Context {
	var extArr []*Extension = make([]*Extension, 0)
	extArr = append(extArr, unloopExtension())

	if accountTaocan == nil {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	//判断套餐是否存在
	if accountTaocan.Number == accountTaocan.NumberUse {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	if accountTaocan.NumberUseTaowai > 0 {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	extArr = append(extArr, globalSettingsExtension())
	extArr = append(extArr, outsideCallExtension(accountTaocan))
	extArr = append(extArr, recordSessionExtension())
	extArr = append(extArr, localUserExtension(destNumber))
	return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
}

// 拨号计划 timer_nocall.wav 超出时间段   risk.wav 命中黑名单
func XMLDialplanContext(destinationNumber string, contextName string, detailsRisk *risk.CustomerRisk, sipsGateway *gateway.SipsGateway, customerGateWay *cgateway.CustomerCgateway, accountTaocan *accounttaocan.YunhuAccountTaocan) []*Context {
	var extArr []*Extension = make([]*Extension, 0)

	extArr = append(extArr, unloopExtension())
	extArr = append(extArr, globalSettingsExtension())

	if accountTaocan == nil {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	extArr = append(extArr, outsideCallExtension(accountTaocan))

	// 判断手机号是否正确
	if !utils.IPhoneNumber(destinationNumber) {
		extArr = append(extArr, hangUpExtension("konghao"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	//判断时间段内是否能拨打
	if detailsRisk.CallDate != "" {
		var callData []string
		json.Unmarshal([]byte(detailsRisk.CallDate), &callData)
		if ok, errs := utils.ChecTimeIsRange(callData); errs == nil && !ok {
			extArr = append(extArr, hangUpExtension("timer_nocall"))
			return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
		}
	}

	//判断套餐是否存在
	if accountTaocan.Number == accountTaocan.NumberUse {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	if accountTaocan.NumberUseTaowai > 0 {
		extArr = append(extArr, hangUpExtension("taocan_no"))
		return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
	}

	extArr = append(extArr, recordSessionExtension())

	extArr = append(extArr, gatewayExtension(sipsGateway, customerGateWay))

	return []*Context{&Context{XMLName: xml.Name{}, Attrname: contextName, Extension: extArr}}
}

func outsideCallExtension(accountTaocan *accounttaocan.YunhuAccountTaocan) *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "outside_call", Attrcontinue: "true", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "outside_call=true"},
			&Action{XMLName: xml.Name{}, Attrapplication: "export", Attrdata: "RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: fmt.Sprintf("customer_id=%d", accountTaocan.CustomerId)},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: fmt.Sprintf("account_id=%d", accountTaocan.AccountId)},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: fmt.Sprintf("taocan_id=%d", accountTaocan.Id)},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: fmt.Sprintf("kind=%d", accountTaocan.Kind)},
		}},
	}}
}

// 全局配置
func globalSettingsExtension() *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "global_settings", Priority: "2", Attrcontinue: "true", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "destination_number", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "x-token=${sip_h_X-token}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "task_track_id=${sip_h_X-Task-Track-Id}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "track_id=${sip_h_X-Track-Id}"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "log", Attrdata: "INFO 新呼叫 - 主叫: ${caller_id_number}, 被叫: ${destination_number}"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "log", Attrdata: "INFO 收到的Authorization: ${sip_h_X-token}"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "log", Attrdata: "INFO 收到的Track-Id: ${sip_h_X-Task-Track-Id}"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "log", Attrdata: "INFO 收到的Track-Id: ${sip_h_X-Track-Id}"},
		}},
	}}
}

func unloopExtension() *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "unloop", Priority: "1", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "${unroll_loops}", Attrexpression: "^true$"},
		&Condition{XMLName: xml.Name{}, Attrfield: "${sip_looped_call}", Attrexpression: "^true$", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "deflect", Attrdata: "${destination_number}"},
		}},
	}}
}

// 内部用户
func localUserExtension(destNumber string) *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "Local_Extension", Priority: "8", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "destination_number", Attrexpression: "^(\\d+)$", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "export", Attrdata: "dialed_extension=$1"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "bind_meta_app", Attrdata: "1 b s execute_extension::dx XML features"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "bind_meta_app", Attrdata: "2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "bind_meta_app", Attrdata: "3 b s execute_extension::cf XML features"},
			//&Action{XMLName: xml.Name{}, Attrapplication: "bind_meta_app", Attrdata: "4 b s execute_extension::att_xfer XML features"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "ringback=${us-ring}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "transfer_ringback=$${hold_music}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "call_timeout=20"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "hangup_after_bridge=true"},
			&Action{XMLName: xml.Name{}, Attrapplication: "bridge", Attrdata: "user/${dialed_extension}@${domain_name}"},
		}},
	}}
}

// 录音控制
func recordSessionExtension() *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "record_session", Priority: "3", Attrcontinue: "true", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "destination_number", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_TITLE=Recording ${destination_number} ${caller_id_number} ${strftime(%Y-%m-%d %H:%M)}"},
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_DATE=${strftime(%Y-%m-%d %H:%M)}"}, //设置录音文件元数据日期
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_STEREO=true"},                      //启用双声道录音  false为单声道
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_ANSWER_REQ=true"},                  //通话接通后开始录音
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_MIN_SEC=1"},                        //最小录音时长（秒）
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_STEREO=false"},                     //启用双声道录音
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "RECORD_APPEND=true"},                      //追加模式录音（不覆盖文件）
			//&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "record_sample_rate=16000"},                  //录音采样率（Hz）
			&Action{XMLName: xml.Name{}, Attrapplication: "record_session", Attrdata: "$${recordings_dir}/${uuid}.mp3"}, //此处为录音文件路径以及 格式为wav   不填格式 则为原始音频录音

		}},
	}}
}

/**
 * 网关控制
 * sipsGateway 小号网关信息
 * customerGateWay 企业网关
 */
func gatewayExtension(sipsGateway *gateway.SipsGateway, customerGateWay *cgateway.CustomerCgateway) *Extension {
	var prefix = ""
	if sipsGateway.GatewayType == 1 {
		prefix = customerGateWay.SmallPrefix
	} else if sipsGateway.GatewayType == 2 {
		prefix = customerGateWay.PowerPrefix
	} else if sipsGateway.GatewayType == 3 {
		prefix = customerGateWay.PlusPrefix
	} else if sipsGateway.GatewayType == 4 {
		prefix = customerGateWay.LinePrefix
	}

	var bridgeGateway = fmt.Sprintf("sofia/gateway/%s/%s$1", sipsGateway.Names, prefix)
	return &Extension{XMLName: xml.Name{}, Attrname: "laikecall", Priority: "4", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "destination_number", Attrexpression: "^(\\d+)$", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "set", Attrdata: "call_timeout=30"},
			&Action{XMLName: xml.Name{}, Attrapplication: "bridge", Attrdata: bridgeGateway},
		}},
	}}
}

// 直接挂断
func hangUpExtension(soundName string) *Extension {
	return &Extension{XMLName: xml.Name{}, Attrname: "filter-rick", Priority: "5", Condition: []*Condition{
		&Condition{XMLName: xml.Name{}, Attrfield: "destination_number", Attrexpression: "^(\\d+)$", Action: []*Action{
			&Action{XMLName: xml.Name{}, Attrapplication: "sleep", Attrdata: "2000"},
			&Action{XMLName: xml.Name{}, Attrapplication: "playback", Attrdata: fmt.Sprintf("$${sounds_dir}/custom/%s.wav", soundName)},
			&Action{XMLName: xml.Name{}, Attrapplication: "sleep", Attrdata: "1000"},
			&Action{XMLName: xml.Name{}, Attrapplication: "hangup", Attrdata: "CALL_REJECTED"},
		}},
	}}
}
